package main

import (
	"fmt"
	"net/http"
	"sync"
	"time"
)

// 用于跟踪服务器状态的全局变量
var (
	serverStatuses       = make(map[string]bool)
	statusMutex          sync.RWMutex
	lastSummaryEmailTime = time.Now().Add(-24 * time.Hour)
	summaryEmailMutex    sync.Mutex
	lastConfigCheck      = time.Now()
	configCheckInterval  = 30 * time.Second
)

func shouldReloadConfig() bool {
	now := time.Now()
	if now.Sub(lastConfigCheck) >= configCheckInterval {
		lastConfigCheck = now
		return true
	}
	return false
}

func CheckServer(server *ServerConfig) (bool, error) {
	client := &http.Client{
		Timeout: 15 * time.Second,
	}

	// 重试3次
	maxRetries := 3
	for i := 0; i < maxRetries; i++ {
		resp, err := client.Get(server.URL)
		if err != nil {
			if i == maxRetries-1 {
				return false, fmt.Errorf("连接失败（已重试%d次）: %v", maxRetries, err)
			}
			time.Sleep(time.Second * 2)
			continue
		}
		defer resp.Body.Close()

		// 接受2xx和3xx的状态码
		if resp.StatusCode >= 200 && resp.StatusCode < 400 {
			return true, nil
		}

		if i == maxRetries-1 {
			return false, fmt.Errorf("服务器返回非正常状态码: %d", resp.StatusCode)
		}
		time.Sleep(time.Second * 2)
	}

	return false, fmt.Errorf("达到最大重试次数")
}

func sendStatusEmail(config *Config, server *ServerConfig, isError bool, errMsg string) {
	currentTime := time.Now().Format("2006-01-02 15:04:05")
	subject := fmt.Sprintf("[%s] 服务器监控警告 - %s", currentTime, server.Name)

	var body string
	if isError {
		body = fmt.Sprintf("服务器 %s (%s) 检查失败:\n%s", server.Name, server.URL, errMsg)
	} else {
		body = fmt.Sprintf("服务器 %s (%s) 可能已宕机", server.Name, server.URL)
	}

	if err := SendEmail(&config.Email, subject, body); err != nil {
		fmt.Printf("发送警告邮件失败: %v\n", err)
	}
}

func sendSummaryEmail(config *Config) {
	now := time.Now()
	currentTime := now.Format("2006-01-02 15:04:05")
	subject := fmt.Sprintf("[%s] 服务器状态汇总", currentTime)

	var serverList string
	statusMutex.RLock()
	for name := range serverStatuses {
		serverList += fmt.Sprintf("- %s\n", name)
	}
	statusMutex.RUnlock()

	body := fmt.Sprintf("所有服务器运行正常:\n%s", serverList)
	if err := SendEmail(&config.Email, subject, body); err != nil {
		fmt.Printf("发送汇总邮件失败: %v\n", err)
	}
	lastSummaryEmailTime = now
}

func MonitorServer(server *ServerConfig, emailConfig *EmailConfig, stopChan <-chan struct{}) {
	// 解析检查间隔
	checkInterval, err := ParseDuration(server.CheckInterval)
	if err != nil {
		fmt.Printf("服务器 %s 的检查间隔解析失败: %v\n", server.Name, err)
		return
	}

	ticker := time.NewTicker(checkInterval)
	defer ticker.Stop()

	// 初始化服务器状态
	statusMutex.Lock()
	serverStatuses[server.Name] = true
	statusMutex.Unlock()

	fmt.Printf("开始监控服务器: %s (URL: %s, 检查间隔: %s)\n",
		server.Name, server.URL, server.CheckInterval)

	for {
		select {
		case <-ticker.C:
			var config *Config
			var err error

			// 只在需要时重新加载配置
			if shouldReloadConfig() {
				config, err = LoadConfig("config.yaml")
				if err != nil {
					fmt.Printf("重新加载配置文件失败: %v\n", err)
					continue
				}
			} else {
				// 使用现有配置
				config = &Config{
					Servers: []ServerConfig{*server},
					Email:   *emailConfig,
				}
			}

			// 更新当前服务器的配置
			var currentServer *ServerConfig
			for _, s := range config.Servers {
				if s.URL == server.URL {
					currentServer = &s
					break
				}
			}

			if currentServer == nil {
				fmt.Printf("服务器 %s 的配置已从配置文件中移除\n", server.Name)
				statusMutex.Lock()
				delete(serverStatuses, server.Name)
				statusMutex.Unlock()
				return
			}

			// 检查服务器是否被禁用
			if !currentServer.Enabled {
				fmt.Printf("服务器 %s 已被禁用，跳过检查\n", server.Name)
				continue
			}

			// 更新检查间隔
			if currentServer.CheckInterval != server.CheckInterval {
				newInterval, err := ParseDuration(currentServer.CheckInterval)
				if err != nil {
					fmt.Printf("服务器 %s 的新检查间隔解析失败: %v\n", server.Name, err)
					continue
				}
				fmt.Printf("服务器 %s 的检查间隔已更新: %s -> %s\n",
					server.Name, server.CheckInterval, currentServer.CheckInterval)
				server.CheckInterval = currentServer.CheckInterval
				ticker.Reset(newInterval)
			}

			// 检查服务器状态
			isUp, err := CheckServer(server)
			if err != nil {
				statusMutex.Lock()
				oldStatus := serverStatuses[server.Name]
				serverStatuses[server.Name] = false
				statusMutex.Unlock()

				if oldStatus {
					sendStatusEmail(config, server, true, err.Error())
				}
				continue
			}

			if !isUp {
				statusMutex.Lock()
				oldStatus := serverStatuses[server.Name]
				serverStatuses[server.Name] = false
				statusMutex.Unlock()

				if oldStatus {
					sendStatusEmail(config, server, false, "")
				}
			} else {
				statusMutex.Lock()
				serverStatuses[server.Name] = true
				statusMutex.Unlock()

				// 检查是否所有服务器都正常
				allServersUp := true
				for _, status := range serverStatuses {
					if !status {
						allServersUp = false
						break
					}
				}

				// 只有当所有服务器都正常，且当前服务器是最后一个被检查的服务器时才发送汇总邮件
				if allServersUp {
					// 检查是否所有服务器都已经完成检查
					allChecked := true
					for _, s := range config.Servers {
						if _, exists := serverStatuses[s.Name]; !exists {
							allChecked = false
							break
						}
					}

					if allChecked {
						// 检查是否距离上次发送汇总邮件已经超过24小时
						summaryEmailMutex.Lock()
						now := time.Now()
						if now.Sub(lastSummaryEmailTime) >= 24*time.Hour {
							sendSummaryEmail(config)
						}
						summaryEmailMutex.Unlock()
					}
				}
			}
		case <-stopChan:
			fmt.Printf("停止监控服务器: %s\n", server.Name)
			return
		}
	}
}
